package com.hefan.oms.service;

import com.cat.common.constant.RedisKeyConstant;
import com.cat.common.meta.ImCustomMsgEnum;
import com.cat.tiger.service.JedisService;
import com.cat.tiger.util.CollectionUtils;
import com.cat.tiger.util.GlobalConstants;
import com.hefan.common.exception.IllegalOperationException;
import com.hefan.live.bean.LiveRoom;
import com.hefan.live.itf.LiveRoomService;
import com.hefan.oms.bean.RebalanceVo;
import com.hefan.oms.itf.AccountService;
import com.hefan.oms.itf.CurrencyExchangeService;
import com.hefan.oms.itf.LiveReBalanceService;
import com.hefan.oms.itf.MessageService;
import com.hefan.user.bean.WebUser;
import com.hefan.user.itf.WebUserService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.profiler.Profiler;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * Created by hbchen on 2016/10/30.
 */
@Component("liveReBalanceService")
public class LiveReBalanceServiceImpl implements LiveReBalanceService {

  private Logger logger = LoggerFactory.getLogger(LiveReBalanceServiceImpl.class);

  @Resource
  private WebUserService webUserService;
  @Resource
  private LiveRoomService liveRoomService;
  @Resource
  private JedisService jedisService;
  @Resource
  private MessageService privateMessageService;
  @Resource
  private CurrencyExchangeService currencyExchangeService;
  @Resource
  private AccountService accountService;


  /**
   * 俱乐部和直播间扣费逻辑：先记录收入/扣费明细、用户经验，发送IM
   * @description 私信和弹幕不记录主播盒饭total，主播income表 所得盒饭归平台所有；
   * @param rebalanceVo
   * @param webUser 送礼人
   * @throws Exception
   */
  @Override
  @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
  public void dealPresentDetail(RebalanceVo rebalanceVo, WebUser webUser) throws Exception {
    Profiler profiler = new Profiler("LiveReBalanceServiceImpl------------------");
    profiler.start("LiveReBalanceServiceImpl-----------记录账户明细，经验");
    //0.俱乐部和直播间记录账目
    int fanPiaoNum = Double.valueOf(rebalanceVo.getPrice()).intValue();
    int hefanNum = currencyExchangeService.exchangeFanPiao2HeFan(fanPiaoNum, GlobalConstants.EX_RULE_FANPIAO_HEFAN);
    profiler.start("LiveReBalanceServiceImpl-----------保存私信内容、发送弹幕");
    //1.保存私信,私信逻辑：不涉及主播盒饭只记录用户消费记录
    if (rebalanceVo.getSource() == GlobalConstants.SOURCE_TYPE_MESSAGE) {
      logger.info("保存用户{}私信内容{}", rebalanceVo.getFromId(), rebalanceVo.getContent());
      privateMessageService.reBalanceMessage(rebalanceVo);
      //处理主播明细、用户经验和扣费明细
      accountService.dealAccountDetail(rebalanceVo, hefanNum, fanPiaoNum, webUser);
      return;
    }else if (rebalanceVo.getSource() == GlobalConstants.SOURCE_TYPE_BARRAGE) {
      logger.info("用户{}发送弹幕内容{}", rebalanceVo.getFromId(), rebalanceVo.getContent());
      //处理主播明细、用户经验和扣费明细
      accountService.dealAccountDetail(rebalanceVo, hefanNum, fanPiaoNum, webUser);
      privateMessageService.dealImMessage(rebalanceVo, ImCustomMsgEnum.BarrageMsg.getType(), rebalanceVo.getContent(), webUser, 0);
      return;
    }
    profiler.start("LiveReBalanceServiceImpl-----------记录主播盒饭total_num" + hefanNum);
    //2.直播间和俱乐部扣费记录主播获得盒饭数,优先记录后续需要im通知直播间盒饭数，私信& 弹幕不记录；
    // 直播间和俱乐部分开记录，主播盒饭total存缓存，直播间小礼物未实际扣费，如果异常会导致total 脏数据
    //直播间扣费
    if (rebalanceVo.getSource() == GlobalConstants.SOURCE_TYPE_LIVE) {
      profiler.start("LiveReBalanceServiceImpl-----------直播间礼物" + rebalanceVo.getPresentName());
      dealLivePresent(rebalanceVo, webUser,hefanNum);
    }else if (rebalanceVo.getSource() == GlobalConstants.SOURCE_TYPE_CLUB) {
      //俱乐部扣费:增加主播盒饭数
      int result = webUserService.icrWebUserHefanTotal(rebalanceVo.getToId(), hefanNum);
      if(result ==0 ){
        logger.error("增加主播={}获得盒饭数={}错误",rebalanceVo.getToId(),hefanNum);
      }
    }
    //3.处理主播明细、用户经验和扣费明细
    profiler.start("LiveReBalanceServiceImpl-----------记账经验");
    accountService.dealAccountDetail(rebalanceVo, hefanNum, fanPiaoNum, webUser);
    // 给队列发消息，完成后续工作
    /*String onsEnv = DynamicProperties.getString("ons.env");
    com.hefan.common.ons.bean.Message message = new com.hefan.common.ons.bean.Message();
    message.setTag(onsEnv);
    message.put("rebalanceVo", URLEncoder.encode(JSON.toJSONString(rebalanceVo),"UTF-8"));
    message.setTopic(TopicRegistry.HEFANTV_OMS_LOG);
    logger.info("liveReBalanceService扣费IM通知前端内容{}", JSON.toJSONString(message));
    onsProducer.sendMsg(message);*/

    //4.2017-02-07 add by 王超：扣费成功后更新主播排行榜：总榜和月榜
//    try {
//      webUserService.updateRankByRebalance(rebalanceVo.getFromId(),rebalanceVo.getToId(), hefanNum);
//    } catch (Exception e) {
//      logger.error("redis更新主播排行榜{}收入{}异常", rebalanceVo.getToId(), hefanNum, e);
//    }
    //5.最后记录本次直播收入,关播后清理缓存
    if (rebalanceVo.getSource() == GlobalConstants.SOURCE_TYPE_LIVE) {
      profiler.start("LiveReBalanceServiceImpl-----------记录本次直播收入");
      try {
        String key = String.format(RedisKeyConstant.ANCHOR_LIVE_INCOME, rebalanceVo.getLiveUuid());
        jedisService.incrBy(key, hefanNum);
      } catch (Exception e) {
        logger.error("redis记录本次直播{}收入{}异常", rebalanceVo.getLiveUuid(), hefanNum, e);
      }
    }
    profiler.stop().print();
  }

  /**
   * 直播间礼物，大礼物，连发小礼物，世界礼物等
   * @description 若小礼物先扣费，再发送IM；
   * @param rebalanceVo
   * @param webUser 送礼人
   * @param hefanNum
   * @throws Exception
   */
  private void dealLivePresent(RebalanceVo rebalanceVo, WebUser webUser, int hefanNum) throws Exception {
    //连发礼物是否发连发，处理redis缓存
    Profiler profiler = new Profiler("LiveReBalanceServiceImpl-----------dealLivePresent-------");
    boolean isIm = true;
    if (rebalanceVo.getHoutaiPresentType() == GlobalConstants.PRESENT_TYPE_SMALL && rebalanceVo.getIsContinue() == 0) {
      logger.info("连发小礼物扣费,查询送礼人信息重新获取账户{}余额", rebalanceVo.getFromId());
      //重新查询用户账户
      webUser = webUserService.getWebUserInfoByUserId(rebalanceVo.getFromId());
      long balance = Double.valueOf(rebalanceVo.getPrice()).longValue();
      if (webUser.getBalance() < balance) {
        logger.error("用户{}余额{}不足本次扣费{}！！", rebalanceVo.getFromId(), webUser.getBalance(), balance);
        throw new IllegalOperationException(String.format("用户%s余额%s不足本次扣费%s！！", rebalanceVo.getFromId(), webUser.getBalance(), balance));
      }
      //连发小礼物重新赋值
      rebalanceVo.setBeforeFanpiao(webUser.getBalance());
      profiler.start("LiveReBalanceServiceImpl-----dealLivePresent------小礼物扣费");
      webUserService.incrWebUserBalance(rebalanceVo.getFromId(), -1 * balance);
      //是否连发礼物
      profiler.start("LiveReBalanceServiceImpl-----dealLivePresent------小礼物缓存");
      isIm = smallContinuePresent(rebalanceVo);
    }
    int result = webUserService.icrWebUserHefanTotal(rebalanceVo.getToId(), hefanNum);
    if(result ==0 ){
      logger.error("增加主播={}获得盒饭数={}错误",rebalanceVo.getToId(),hefanNum);
    }
    profiler.start("LiveReBalanceServiceImpl-----dealLivePresent------发送IM" + isIm);
    //直播间和俱乐部才送礼物,如果连发礼物中断不发im
    if (isIm) {
      //自定义消息礼物im
      privateMessageService.dealImMessage(rebalanceVo, ImCustomMsgEnum.LivePresent.getType(), ImCustomMsgEnum.LivePresent.getMsg(), webUser, 0);
      //盒饭数im
      privateMessageService.dealImMessage(rebalanceVo, ImCustomMsgEnum.PresentChange.getType(), ImCustomMsgEnum.PresentChange.getMsg(), webUser, 0);
    }
    profiler.start("LiveReBalanceServiceImpl-----dealLivePresent------世界礼物");
    //世界礼物群发
    if (rebalanceVo.getHoutaiPresentType() == GlobalConstants.PRESENT_TYPE_WORLD) {
      //世界礼物im通知 查询所有正在直播的roomid 广播消息
      List<LiveRoom> roomList = liveRoomService.getLivingRoomList();
      if (!CollectionUtils.isEmpty(roomList)) {
        for (LiveRoom room : roomList) {
          //排除当前直播间礼物
          // if (room.getLiveUuid().equals(rebalanceVo.getLiveUuid())) {
          //世界礼物Im 发送源官方账户
          rebalanceVo.setRoomId(String.valueOf(room.getId()));
          rebalanceVo.setToId(GlobalConstants.HEFAN_OFFICIAL_ID);
          privateMessageService.dealImMessage(rebalanceVo, ImCustomMsgEnum.LivePresent.getType(), ImCustomMsgEnum.LivePresent.getMsg(), webUser, 0);
          // }
        }

      }
    }
    profiler.stop().print();
  }



  /**
   * 连发小礼物，更新redis缓存，如果redis存储大于礼物数
   *
   * @param rebalanceVo
   * @return boolean
   * @throws
   * @author wangchao
   * @create 2016/11/2 11:27
   */
  private boolean smallContinuePresent(RebalanceVo rebalanceVo) {
    if (rebalanceVo.getHoutaiPresentType() == GlobalConstants.PRESENT_TYPE_SMALL && rebalanceVo.getIsContinue() == 0) {

      String key = String.format(RedisKeyConstant.CONTINUE_PRESENT_NUM_KEY, rebalanceVo.getUniqueKey());
      try {
        String presentNumStr = jedisService.getStr(key);
        logger.info("连发礼物redis对应的key：{}，当前礼物数:{},本次发送礼物数{}", key, presentNumStr, rebalanceVo.getPresentNum());
        if (StringUtils.isNotBlank(presentNumStr)) {
          int pNum = Integer.valueOf(presentNumStr);
          jedisService.setexStr(key, String.valueOf(pNum + 1), RedisKeyConstant.CONTINUE_PRESENT_NUM_SECONDS);
          if (pNum + 1 > rebalanceVo.getPresentNum()) {
            return false;
          }
        } else {
          jedisService.setexStr(key, "1", RedisKeyConstant.CONTINUE_PRESENT_NUM_SECONDS);//重置
        }

      } catch (Exception e) {
        logger.error("连发礼物redis 处理异常", e);
        return false;
      }
    }
    return true;
  }
}
